package com.gzhryc.shared_device.cdcz.core.protocol.v2;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.utils.JsonTools;
import com.gzhryc.shared_device.cdcz.core.CDCZConstants;
import com.gzhryc.shared_device.cdcz.core.ICDCZNetworkEventListener;
import com.gzhryc.shared_device.cdcz.core.enums.ECDCZPlugOverloadState;
import com.gzhryc.shared_device.cdcz.core.enums.ECDCZPlugPowerState;
import com.gzhryc.shared_device.cdcz.core.enums.ECDCZPlugTemperatureState;
import com.gzhryc.shared_device.cdcz.core.enums.ECDCZPlugWorkState;
import com.gzhryc.shared_device.cdcz.core.models.*;
import com.gzhryc.shared_device.cdcz.core.protocol.v2.models.*;
import com.gzhryc.shared_device.iot.code.IIOTLogServer;
import com.gzhryc.shared_device.iot.code.dao.db.IOTLogsRecord;
import com.gzhryc.shared_device.iot.code.dao.enums.ELogType;
import com.gzhryc.shared_device.iot.core.IOTClientEvent;
import com.gzhryc.shared_device.iot.core.IOTClientEventListener;
import com.gzhryc.shared_device.iot.core.IOTMessage;

import java.util.ArrayList;

public class V2_CDCZ_IOTClientEventListener implements IOTClientEventListener {

    static Logger log = Logger.getLogger(V2_CDCZ_IOTClientEventListener.class);

    private final IIOTLogServer logServer;
    private final ICDCZNetworkEventListener eventListener;

    public V2_CDCZ_IOTClientEventListener(IIOTLogServer logServer, ICDCZNetworkEventListener eventListener){
        this.logServer = logServer;
        this.eventListener = eventListener;
    }

    @Override
    public void active(IOTClientEvent event) {

    }

    @Override
    public void receiveMessage(IOTClientEvent event) {
        V2_CDCZ_IOTMessage message = null;
        try {
            message = event.getMessage().fromJSON(V2_CDCZ_IOTMessage.class);
            //记录日志
            IOTLogsRecord eventEntity = new IOTLogsRecord();
            eventEntity.setType(ELogType.DeviceLog.name());
            eventEntity.setIotId(event.getClient().getIOTNote().getId());
            eventEntity.setDeviceSn(message.getDEVICE());
            eventEntity.setIotTopic(event.getMessage().getTopic());
            eventEntity.setContent(event.getMessage().getString());
            eventEntity.setMsgId(message.getSEQ());
            eventEntity.setProtocolType(CDCZConstants.ProtocolTypeV2);
            eventEntity.setCommand(message.getCMD().toString());
            logServer.send(eventEntity);
        } catch (Exception e) {
            log.error("接收IOT信息错误，内容：{{1}}", e, event.getMessage().getString());

            //记录日志
            IOTLogsRecord eventEntity = new IOTLogsRecord();
            eventEntity.setType(ELogType.DeviceLog.name());
            eventEntity.setIotId(event.getClient().getIOTNote().getId());
            eventEntity.setDeviceSn(event.getDeviceSn());
            eventEntity.setIotTopic(event.getMessage().getTopic());
            eventEntity.setContent(event.getMessage().getString());
            eventEntity.setMsgId("---");
            eventEntity.setProtocolType(CDCZConstants.ProtocolTypeV2);
            eventEntity.setCommand("解析失败");
            logServer.send(eventEntity);
        }
        if(message != null && message.getCMD() != null) {
            try {
                if (1 == message.getCMD()) {
                    V2CDCZHeartbeatRequest iotReq = event.getMessage().fromJSON(V2CDCZHeartbeatRequest.class);
                    //心跳
                    CDCZHeartbeatNotify notify = new CDCZHeartbeatNotify();
                    notify.setDeviceSn(iotReq.getDEVICE());
                    notify.setRssi(iotReq.getRSSI());
                    notify.setMcuTemperature(iotReq.getTEMP().doubleValue());

                    if(iotReq.getALLDATA() != null && iotReq.getALLDATA().size() > 0){
                        if (notify.getPlugInfoList() == null) {
                            notify.setPlugInfoList(new ArrayList<>());
                        }
                        for(V2CDCZSlot slot : iotReq.getALLDATA()){
                            CDCZPlugInfo info = new CDCZPlugInfo();
                            info.setSlotNum(slot.getPort());
                            info.setNowPower(slot.getPower().doubleValue());
                            info.setChargedTime(slot.getOutTime());   //已充时间
                            info.setWorkState(ECDCZPlugWorkState.NotCharge.index());
                            info.setPowerState(ECDCZPlugPowerState.NoElectricity.index());
                            info.setOverloadState(ECDCZPlugOverloadState.Normal.index());
                            info.setTemperatureState(ECDCZPlugTemperatureState.Normal.index());
                            if(slot.getBtStat() == 1){
                                info.setWorkState(ECDCZPlugWorkState.Charge.index());
                                info.setPowerState(ECDCZPlugPowerState.Energize.index());
                            }else if(slot.getBtStat() == 2){
                                info.setWorkState(ECDCZPlugWorkState.TimesFillStop.index());
                            }else if(slot.getBtStat() == 3){
                                info.setWorkState(ECDCZPlugWorkState.PowerFillStop.index());
                            }else if(slot.getBtStat() == 4){
                                info.setWorkState(ECDCZPlugWorkState.OutStop.index());
                            }else if(slot.getBtStat() == 5){
                                //功率过大
                                info.setOverloadState(ECDCZPlugOverloadState.overload.index());
                            }else if(slot.getBtStat() == 6){
                                //端口异常
                            }else if(slot.getBtStat() == 7){
                                //高温报警
                                info.setTemperatureState(ECDCZPlugTemperatureState.High.index());
                            }
                            notify.getPlugInfoList().add(info);
                        }
                    }

                    this.eventListener.heartbeat(event.getClient(),notify);

                    V2CDCZHeartbeatResponse iotResp = ClassTools.copy(new V2CDCZHeartbeatResponse(),iotReq);

                    V2_CDCZ_IOTCloudMessage cloudMessage = new V2_CDCZ_IOTCloudMessage(JsonTools.toJson(iotResp));
                    cloudMessage.setCmd(iotResp.getCMD().toString());
                    cloudMessage.setDeviceSn(iotResp.getDEVICE());
                    cloudMessage.setMessageId(iotResp.getSEQ());
                    cloudMessage.setTopic("/" + iotResp.getDEVICE() + "/user/get");
                    event.getClient().send(cloudMessage);

                }else if(2 == message.getCMD()) {
                    V2CDCZSlotInfoRequest iotReq = event.getMessage().fromJSON(V2CDCZSlotInfoRequest.class);
                    if(iotReq.getALLDATA() != null && iotReq.getALLDATA().size() > 0){
                        for(V2CDCZSlot slot : iotReq.getALLDATA()){
                            if(slot.getBtStat() == 2 || slot.getBtStat() == 3 || slot.getBtStat() == 4) {
                                CDCZChargeCloseNotify closeNotify = new CDCZChargeCloseNotify();
                                closeNotify.setDeviceSn(iotReq.getDEVICE());
                                closeNotify.setSlotNum(slot.getPort());
                                closeNotify.setNowPower(slot.getPower().doubleValue());
                                closeNotify.setChargedTime(slot.getOutTime());
                                if(slot.getBtStat() == 2){
                                    closeNotify.setWorkState(ECDCZPlugWorkState.TimesFillStop.index());
                                }else if(slot.getBtStat() == 3){
                                    closeNotify.setWorkState(ECDCZPlugWorkState.PowerFillStop.index());
                                }else if(slot.getBtStat() == 4){
                                    closeNotify.setWorkState(ECDCZPlugWorkState.OutStop.index());
                                }
                                this.eventListener.chargeClose(closeNotify);
                            }
                        }
                    }

                    V2CDCZSlotInfoResponse iotResp = ClassTools.copy(new V2CDCZSlotInfoResponse(),iotReq);

                    V2_CDCZ_IOTCloudMessage cloudMessage = new V2_CDCZ_IOTCloudMessage(JsonTools.toJson(iotResp));
                    cloudMessage.setCmd(iotResp.getCMD().toString());
                    cloudMessage.setDeviceSn(iotResp.getDEVICE());
                    cloudMessage.setMessageId(iotResp.getSEQ());
                    cloudMessage.setTopic("/" + iotResp.getDEVICE() + "/user/get");
                    event.getClient().send(cloudMessage);

                }else if(3 == message.getCMD()) {
                    //设备卡槽充电
                    V2CDCZChargeResponse iotResp = event.getMessage().fromJSON(V2CDCZChargeResponse.class);

                    CDCZChargeStartupResultNotify notify = new CDCZChargeStartupResultNotify();
                    notify.setDeviceSn(iotResp.getDEVICE());
                    notify.setMessageId(iotResp.getSEQ());
                    notify.setSlotNum(iotResp.getPORT());
                    notify.setResultCode(CDCZExecuteResult.SUCCESS);

                    if(iotResp.getALLDATA() != null && iotResp.getALLDATA().size() > 0){
                        V2CDCZSlot slot = null;
                        for(V2CDCZSlot item : iotResp.getALLDATA()){
                            if(item.getPort().equals(notify.getSlotNum())){
                                if(item.getBtStat() == 0){
                                    notify.setResultCode(CDCZExecuteResult.FAIL);
                                }
                                break;
                            }
                        }
                    }
                    this.eventListener.chargeStartupResult(event.getClient(),notify);

                }else if(4 == message.getCMD()) {
                    //设备卡槽充电结束
                    V2CDCZCloseChargeResponse iotResp = event.getMessage().fromJSON(V2CDCZCloseChargeResponse.class);

                    CDCZChargeCloseNotify notify = new CDCZChargeCloseNotify();
                    notify.setDeviceSn(iotResp.getDEVICE());
                    notify.setSlotNum(iotResp.getPORT());

                    V2CDCZSlot slot = null;
                    if(iotResp.getALLDATA() != null && iotResp.getALLDATA().size() > 0){
                        for(V2CDCZSlot item : iotResp.getALLDATA()){
                            if(item.getPort().equals(iotResp.getPORT())){
                                slot = item;
                                break;
                            }
                        }
                    }

                    if(slot != null) {
                        notify.setNowPower(slot.getPower().doubleValue());
                        notify.setChargedTime(slot.getOutTime());
                        notify.setWorkState(ECDCZPlugWorkState.ForceStop.index());
                        if(slot.getBtStat() == 1){
                            notify.setWorkState(ECDCZPlugWorkState.Charge.index());
                        }else if(slot.getBtStat() == 2){
                            notify.setWorkState(ECDCZPlugWorkState.TimesFillStop.index());
                        }else if(slot.getBtStat() == 3){
                            notify.setWorkState(ECDCZPlugWorkState.PowerFillStop.index());
                        }else if(slot.getBtStat() == 4){
                            notify.setWorkState(ECDCZPlugWorkState.OutStop.index());
                        }else if(slot.getBtStat() == 5){
                            //功率过大
                        }else if(slot.getBtStat() == 6){
                            //端口异常
                        }else if(slot.getBtStat() == 7){
                            //高温报警
                        }
                    }

                    this.eventListener.chargeClose(notify);

                }else if(5 == message.getCMD()) {
                    //设备查询返回
                    V2CDCZSearchResponse iotResp = event.getMessage().fromJSON(V2CDCZSearchResponse.class);

                    CDCZSearchResultNotify notify = new CDCZSearchResultNotify();
                    notify.setDeviceSn(iotResp.getDEVICE());

                    if(iotResp.getALLDATA() != null && iotResp.getALLDATA().size() > 0){
                        if (notify.getPlugInfoList() == null) {
                            notify.setPlugInfoList(new ArrayList<>());
                        }
                        for(V2CDCZSlot slot : iotResp.getALLDATA()){
                            CDCZPlugInfo info = new CDCZPlugInfo();
                            info.setSlotNum(slot.getPort());
                            info.setNowPower(slot.getPower().doubleValue());
                            info.setChargedTime(slot.getOutTime());   //已充时间
                            info.setWorkState(ECDCZPlugWorkState.NotCharge.index());
                            info.setPowerState(ECDCZPlugPowerState.NoElectricity.index());
                            info.setOverloadState(ECDCZPlugOverloadState.Normal.index());
                            info.setTemperatureState(ECDCZPlugTemperatureState.Normal.index());
                            if(slot.getBtStat() == 1){
                                info.setWorkState(ECDCZPlugWorkState.Charge.index());
                                info.setPowerState(ECDCZPlugPowerState.Energize.index());
                            }else if(slot.getBtStat() == 2){
                                info.setWorkState(ECDCZPlugWorkState.TimesFillStop.index());
                            }else if(slot.getBtStat() == 3){
                                info.setWorkState(ECDCZPlugWorkState.PowerFillStop.index());
                            }else if(slot.getBtStat() == 4){
                                info.setWorkState(ECDCZPlugWorkState.OutStop.index());
                            }else if(slot.getBtStat() == 5){
                                //功率过大
                                info.setWorkState(ECDCZPlugWorkState.Charge.index());
                                info.setOverloadState(ECDCZPlugOverloadState.overload.index());
                            }else if(slot.getBtStat() == 6){
                                //端口异常
                            }else if(slot.getBtStat() == 7){
                                //高温报警
                                info.setWorkState(ECDCZPlugWorkState.Charge.index());
                                info.setTemperatureState(ECDCZPlugTemperatureState.High.index());
                            }
                            notify.getPlugInfoList().add(info);
                        }
                    }

                    this.eventListener.searchResult(event.getClient(),notify);

                }else if(10 == message.getCMD()) {
                    //设备重启
                    V2CDCZRestartResponse iotResp = event.getMessage().fromJSON(V2CDCZRestartResponse.class);

                }else if(20 == message.getCMD()) {
                    //绑定从机
                    V2CDCZBindSlaveDeviceResponse iotResp = event.getMessage().fromJSON(V2CDCZBindSlaveDeviceResponse.class);

                    CDCZBindSlaveDeviceNotify notify = new CDCZBindSlaveDeviceNotify();
                    notify.setDeviceSn(iotResp.getDEVICE());
                    notify.setBindIndex(iotResp.getSLAVENUM());

                    this.eventListener.bindSlaveDevice(notify);

                }else if(21 == message.getCMD()) {
                    //移除从机
                    V2CDCZRemoveSlaveDeviceResponse iotResp = event.getMessage().fromJSON(V2CDCZRemoveSlaveDeviceResponse.class);

                    CDCZRemoveSlaveDeviceNotify notify = new CDCZRemoveSlaveDeviceNotify();
                    notify.setDeviceSn(iotResp.getDEVICE());

                    this.eventListener.removeSlaveDevice(notify);

                }else if(50 == message.getCMD()) {
                    //查询从机
                    V2CDCZFindSlaveDeviceResponse iotResp = event.getMessage().fromJSON(V2CDCZFindSlaveDeviceResponse.class);

                    String slaveDeviceSn = iotResp.getSLAVENAME();
                    if(slaveDeviceSn.startsWith("XH_")){
                        slaveDeviceSn = slaveDeviceSn.substring(3);
                        if(slaveDeviceSn.equals("000000000000")){
                            slaveDeviceSn = null;
                        }
                    }

                    CDCZFindSlaveDeviceResultNotify notify = new CDCZFindSlaveDeviceResultNotify();
                    notify.setDeviceSn(iotResp.getDEVICE());
                    notify.setBindIndex(iotResp.getSLAVENUM());
                    notify.setSlaveDeviceSn(slaveDeviceSn);

                    this.eventListener.findSlaveDevice(notify);

                }else if (0 == message.getCMD()) {
                    V2CDCZDeviceLoginRequest iotReq = event.getMessage().fromJSON(V2CDCZDeviceLoginRequest.class);
                    //设备启动
                    CDCZOnlineNotify notify = new CDCZOnlineNotify();
                    notify.setDeviceSn(iotReq.getDEVICE());
                    notify.setVersion(iotReq.getVERSION());
                    notify.setIccid(iotReq.getICCID());
                    notify.setRssi(iotReq.getRSSI());
                    notify.setType(1);

                    if (this.eventListener.online(notify)) {
                        V2CDCZDeviceLoginResponse iotResp = ClassTools.copy(new V2CDCZDeviceLoginResponse(),iotReq);

                        V2_CDCZ_IOTCloudMessage cloudMessage = new V2_CDCZ_IOTCloudMessage(JsonTools.toJson(iotResp));
                        cloudMessage.setCmd(iotResp.getCMD().toString());
                        cloudMessage.setDeviceSn(iotResp.getDEVICE());
                        cloudMessage.setMessageId(iotResp.getSEQ());
                        cloudMessage.setTopic("/" + iotResp.getDEVICE() + "/user/get");
                        event.getClient().send(cloudMessage);
                    }
                }
            } catch (Exception e) {
                log.error("接收IOT信息错误，主题：{{1}}，原始报文：{{2:json}}", e, event.getMessage().getTopic(), event.getMessage().byte2Hex());
            }
        }
    }

    @Override
    public void stateChange(IOTClientEvent event) {
        log.info("～～～设备上下线变更～～～");
    }

    @Override
    public void sendMessage(IOTMessage msg, Long iotId, String topic) {
        //记录日志
        IOTLogsRecord eventEntity = new IOTLogsRecord();
        eventEntity.setType(ELogType.CloudLog.name());
        eventEntity.setIotId(iotId);
        eventEntity.setDeviceSn(msg.getDeviceSn());
        eventEntity.setIotTopic(topic);
        eventEntity.setContent(msg.getString());
        eventEntity.setMsgId(msg.getMessageId());
        eventEntity.setProtocolType(CDCZConstants.ProtocolTypeV2);
        eventEntity.setCommand(msg.getCmd());
        logServer.send(eventEntity);
    }
}
